{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Scikit-Learn IRIS Model using jsonData\n",
    "\n",
    " * Wrap a scikit-learn python model for use as a prediction microservice in seldon-core\n",
    "   * Run locally on Docker to test\n",
    "   * Deploy on seldon-core running on minikube\n",
    " \n",
    "## Dependencies\n",
    "\n",
    " * [Helm](https://github.com/kubernetes/helm)\n",
    " * [Minikube](https://github.com/kubernetes/minikube)\n",
    " * [S2I](https://github.com/openshift/source-to-image)\n",
    "\n",
    "```bash\n",
    "pip install sklearn\n",
    "pip install seldon-core\n",
    "```\n",
    "\n",
    "## Train locally\n",
    " "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Loading iris data set...\n",
      "Dataset loaded!\n",
      "Training model...\n",
      "Model trained!\n",
      "Saving model in IrisClassifier.sav\n",
      "Model saved!\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import os\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "from sklearn.pipeline import Pipeline\n",
    "from sklearn.externals import joblib\n",
    "from sklearn import datasets\n",
    "\n",
    "def main():\n",
    "    clf = LogisticRegression()\n",
    "    p = Pipeline([('clf', clf)])\n",
    "    print('Training model...')\n",
    "    p.fit(X, y)\n",
    "    print('Model trained!')\n",
    "\n",
    "    filename_p = 'IrisClassifier.sav'\n",
    "    print('Saving model in %s' % filename_p)\n",
    "    joblib.dump(p, filename_p)\n",
    "    print('Model saved!')\n",
    "    \n",
    "if __name__ == \"__main__\":\n",
    "    print('Loading iris data set...')\n",
    "    iris = datasets.load_iris()\n",
    "    X, y = iris.data, iris.target\n",
    "    print('Dataset loaded!')\n",
    "    main()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## REST test"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Wrap model using s2i"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "---> Installing application source...\n",
      "---> Installing dependencies ...\n",
      "Looking in links: /whl\n",
      "Collecting scikit-learn==0.19.0 (from -r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/a4/b3/209652a5d60ce4a2a8a35ad893d7565bbb0f87ce043264ba5c9e7de304cd/scikit_learn-0.19.0-cp36-cp36m-manylinux1_x86_64.whl (12.4MB)\n",
      "Collecting scipy==0.18.1 (from -r requirements.txt (line 2))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/74/c0/f0bf4eaef1b6aa7bdd1ae5597ce1d9e729417b3ca085c47d0f1c640d34f8/scipy-0.18.1-cp36-cp36m-manylinux1_x86_64.whl (42.5MB)\n",
      "Installing collected packages: scikit-learn, scipy\n",
      "Successfully installed scikit-learn-0.19.0 scipy-0.18.1\n",
      "WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "WARNING: You are using pip version 19.1, however version 19.1.1 is available.\n",
      "You should consider upgrading via the 'pip install --upgrade pip' command.\n",
      "Build completed successfully\n"
     ]
    }
   ],
   "source": [
    "!s2i build . seldonio/seldon-core-s2i-python3:0.13 sklearn-iris-jsondata:0.1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Serve model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "c72f210d5669ede4055990e3ea2b4d167a1a5c5b17d0cd3b3837e5bf17fbc4e5\r\n"
     ]
    }
   ],
   "source": [
    "!docker run --name \"iris_predictor\" -d --rm -p 5000:5000 sklearn-iris-jsondata:0.1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\n",
      "  \"data\": {\n",
      "    \"names\": [\n",
      "      \"t:0\",\n",
      "      \"t:1\",\n",
      "      \"t:2\"\n",
      "    ],\n",
      "    \"tensor\": {\n",
      "      \"shape\": [\n",
      "        1,\n",
      "        3\n",
      "      ],\n",
      "      \"values\": [\n",
      "        0.0011809149535246906,\n",
      "        0.7867455841528153,\n",
      "        0.21207350089366006\n",
      "      ]\n",
      "    }\n",
      "  },\n",
      "  \"meta\": {}\n",
      "}\n"
     ]
    }
   ],
   "source": [
    "%%bash\n",
    "\n",
    "#\n",
    "# Send some random features to model\n",
    "#\n",
    "\n",
    "curl -sg http://localhost:5000/predict --data-urlencode 'json=\n",
    "{\n",
    "    \"jsonData\": {\n",
    "        \"some_data\": {\n",
    "            \"names\": [\n",
    "                \"sepal_length\",\n",
    "                \"sepal_width\",\n",
    "                \"petal_length\",\n",
    "                \"petal_width\"\n",
    "            ],\n",
    "            \"some_ndarray\": [\n",
    "                [\n",
    "                    7.233,\n",
    "                    4.652,\n",
    "                    7.39,\n",
    "                    0.324\n",
    "                ]\n",
    "            ]\n",
    "        }\n",
    "    }\n",
    "}' | jq"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Stop serving model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "iris_predictor\r\n"
     ]
    }
   ],
   "source": [
    "!docker rm iris_predictor --force"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Test using Minikube\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!minikube start --memory 4096"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "clusterrolebinding.rbac.authorization.k8s.io/kube-system-cluster-admin created\r\n"
     ]
    }
   ],
   "source": [
    "!kubectl create clusterrolebinding kube-system-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:default"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "$HELM_HOME has been configured at /home/gsunner/.helm.\n",
      "\n",
      "Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster.\n",
      "\n",
      "Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.\n",
      "For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation\n",
      "Happy Helming!\n"
     ]
    }
   ],
   "source": [
    "!helm init"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "deployment \"tiller-deploy\" successfully rolled out\r\n"
     ]
    }
   ],
   "source": [
    "!kubectl rollout status deploy/tiller-deploy -n kube-system"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "NAME:   seldon-core\n",
      "LAST DEPLOYED: Tue Jul  9 11:32:59 2019\n",
      "NAMESPACE: seldon-system\n",
      "STATUS: DEPLOYED\n",
      "\n",
      "RESOURCES:\n",
      "==> v1/ClusterRole\n",
      "NAME                          AGE\n",
      "seldon-operator-manager-role  0s\n",
      "\n",
      "==> v1/Service\n",
      "NAME                                        TYPE       CLUSTER-IP     EXTERNAL-IP  PORT(S)  AGE\n",
      "seldon-operator-controller-manager-service  ClusterIP  10.98.37.166   <none>       443/TCP  0s\n",
      "webhook-server-service                      ClusterIP  10.105.235.39  <none>       443/TCP  0s\n",
      "\n",
      "==> v1beta1/Deployment\n",
      "NAME                        DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE\n",
      "seldon-spartakus-volunteer  1        1        1           0          0s\n",
      "\n",
      "==> v1/StatefulSet\n",
      "NAME                                DESIRED  CURRENT  AGE\n",
      "seldon-operator-controller-manager  1        1        0s\n",
      "\n",
      "==> v1beta1/ClusterRole\n",
      "NAME                        AGE\n",
      "seldon-spartakus-volunteer  0s\n",
      "\n",
      "==> v1/ClusterRoleBinding\n",
      "NAME                                 AGE\n",
      "seldon-operator-manager-rolebinding  0s\n",
      "\n",
      "==> v1beta1/ClusterRoleBinding\n",
      "seldon-spartakus-volunteer  0s\n",
      "\n",
      "==> v1/Pod(related)\n",
      "NAME                                         READY  STATUS             RESTARTS  AGE\n",
      "seldon-spartakus-volunteer-7d6dd98f89-dzr5k  0/1    ContainerCreating  0         0s\n",
      "seldon-operator-controller-manager-0         0/1    ContainerCreating  0         0s\n",
      "\n",
      "==> v1/Secret\n",
      "NAME                                   TYPE    DATA  AGE\n",
      "seldon-operator-webhook-server-secret  Opaque  0     0s\n",
      "\n",
      "==> v1/ConfigMap\n",
      "NAME                     DATA  AGE\n",
      "seldon-spartakus-config  1     0s\n",
      "\n",
      "==> v1/ServiceAccount\n",
      "NAME                              SECRETS  AGE\n",
      "seldon-core-seldon-core-operator  1        0s\n",
      "seldon-spartakus-volunteer        1        0s\n",
      "\n",
      "==> v1beta1/CustomResourceDefinition\n",
      "NAME                                         AGE\n",
      "seldondeployments.machinelearning.seldon.io  0s\n",
      "\n",
      "\n",
      "NOTES:\n",
      "NOTES: TODO\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "!helm install ../../../helm-charts/seldon-core-operator --name seldon-core --set usageMetrics.enabled=true   --namespace seldon-system"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Waiting for 1 pods to be ready...\n",
      "partitioned roll out complete: 1 new pods have been updated...\n"
     ]
    }
   ],
   "source": [
    "!kubectl rollout status deploy/seldon-controller-manager -n seldon-system"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Setup Ingress\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "NAME:   ambassador\n",
      "LAST DEPLOYED: Tue Jul  9 11:33:20 2019\n",
      "NAMESPACE: default\n",
      "STATUS: DEPLOYED\n",
      "\n",
      "RESOURCES:\n",
      "==> v1beta1/ClusterRole\n",
      "NAME        AGE\n",
      "ambassador  0s\n",
      "\n",
      "==> v1beta1/ClusterRoleBinding\n",
      "NAME        AGE\n",
      "ambassador  0s\n",
      "\n",
      "==> v1/Service\n",
      "NAME               TYPE          CLUSTER-IP      EXTERNAL-IP  PORT(S)                     AGE\n",
      "ambassador-admins  ClusterIP     10.111.150.168  <none>       8877/TCP                    0s\n",
      "ambassador         LoadBalancer  10.108.34.71    <pending>    80:30241/TCP,443:32292/TCP  0s\n",
      "\n",
      "==> v1/Deployment\n",
      "NAME        DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE\n",
      "ambassador  3        3        3           0          0s\n",
      "\n",
      "==> v1/Pod(related)\n",
      "NAME                         READY  STATUS             RESTARTS  AGE\n",
      "ambassador-78bd586dc9-9r6f7  0/1    ContainerCreating  0         0s\n",
      "ambassador-78bd586dc9-hwcp4  0/1    ContainerCreating  0         0s\n",
      "ambassador-78bd586dc9-kctmz  0/1    ContainerCreating  0         0s\n",
      "\n",
      "==> v1/ServiceAccount\n",
      "NAME        SECRETS  AGE\n",
      "ambassador  1        1s\n",
      "\n",
      "==> v1beta1/CustomResourceDefinition\n",
      "NAME                                          AGE\n",
      "modules.getambassador.io                      1s\n",
      "tracingservices.getambassador.io              1s\n",
      "tlscontexts.getambassador.io                  1s\n",
      "tcpmappings.getambassador.io                  1s\n",
      "authservices.getambassador.io                 1s\n",
      "consulresolvers.getambassador.io              1s\n",
      "kubernetesendpointresolvers.getambassador.io  1s\n",
      "mappings.getambassador.io                     1s\n",
      "ratelimitservices.getambassador.io            0s\n",
      "kubernetesserviceresolvers.getambassador.io   0s\n",
      "\n",
      "\n",
      "NOTES:\n",
      "Congratuations! You've successfully installed Ambassador.\n",
      "\n",
      "For help, visit our Slack at https://d6e.co/slack or view the documentation online at https://www.getambassador.io.\n",
      "\n",
      "To get the IP address of Ambassador, run the following commands:\n",
      "NOTE: It may take a few minutes for the LoadBalancer IP to be available.\n",
      "     You can watch the status of by running 'kubectl get svc -w  --namespace default ambassador'\n",
      "\n",
      "  On GKE/Azure:\n",
      "  export SERVICE_IP=$(kubectl get svc --namespace default ambassador -o jsonpath='{.status.loadBalancer.ingress[0].ip}')\n",
      "\n",
      "  On AWS:\n",
      "  export SERVICE_IP=$(kubectl get svc --namespace default ambassador -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')\n",
      "\n",
      "  echo http://$SERVICE_IP:\n",
      "\n"
     ]
    }
   ],
   "source": [
    "!helm install stable/ambassador --name ambassador --set crds.keep=false"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Waiting for deployment \"ambassador\" rollout to finish: 0 of 3 updated replicas are available...\n",
      "Waiting for deployment \"ambassador\" rollout to finish: 1 of 3 updated replicas are available...\n",
      "Waiting for deployment \"ambassador\" rollout to finish: 2 of 3 updated replicas are available...\n",
      "deployment \"ambassador\" successfully rolled out\n"
     ]
    }
   ],
   "source": [
    "!kubectl rollout status deployment.apps/ambassador"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Wrap Model and Test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "---> Installing application source...\n",
      "---> Installing dependencies ...\n",
      "Looking in links: /whl\n",
      "Collecting scikit-learn==0.19.0 (from -r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/a4/b3/209652a5d60ce4a2a8a35ad893d7565bbb0f87ce043264ba5c9e7de304cd/scikit_learn-0.19.0-cp36-cp36m-manylinux1_x86_64.whl (12.4MB)\n",
      "Collecting scipy==0.18.1 (from -r requirements.txt (line 2))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/74/c0/f0bf4eaef1b6aa7bdd1ae5597ce1d9e729417b3ca085c47d0f1c640d34f8/scipy-0.18.1-cp36-cp36m-manylinux1_x86_64.whl (42.5MB)\n",
      "Installing collected packages: scikit-learn, scipy\n",
      "Successfully installed scikit-learn-0.19.0 scipy-0.18.1\n",
      "WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "WARNING: You are using pip version 19.1, however version 19.1.1 is available.\n",
      "You should consider upgrading via the 'pip install --upgrade pip' command.\n",
      "Build completed successfully\n"
     ]
    }
   ],
   "source": [
    "!eval $(minikube docker-env) && s2i build . seldonio/seldon-core-s2i-python3:0.13 sklearn-iris-jsondata:0.1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "seldondeployment.machinelearning.seldon.io/seldon-deployment-example created\r\n"
     ]
    }
   ],
   "source": [
    "!kubectl create -f sklearn_iris_jsondata_deployment.json"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Waiting for deployment \"sklearn-iris-deployment-sklearn-iris-predictor-5d3a732\" rollout to finish: 0 of 1 updated replicas are available...\n",
      "deployment \"sklearn-iris-deployment-sklearn-iris-predictor-5d3a732\" successfully rolled out\n"
     ]
    }
   ],
   "source": [
    "!kubectl rollout status deploy/$(kubectl get deploy -l seldon-app=sklearn-iris-deployment-sklearn-iris-predictor --no-headers=true|cut -d' ' -f1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Test by sending prediction calls"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\n",
      "  \"meta\": {\n",
      "    \"puid\": \"6d6jdiqbbtd01qbqdapjmlqc6d\",\n",
      "    \"tags\": {},\n",
      "    \"routing\": {},\n",
      "    \"requestPath\": {\n",
      "      \"sklearn-iris-classifier\": \"sklearn-iris-jsondata:0.1\"\n",
      "    },\n",
      "    \"metrics\": []\n",
      "  },\n",
      "  \"data\": {\n",
      "    \"names\": [\n",
      "      \"t:0\",\n",
      "      \"t:1\",\n",
      "      \"t:2\"\n",
      "    ],\n",
      "    \"tensor\": {\n",
      "      \"shape\": [\n",
      "        1,\n",
      "        3\n",
      "      ],\n",
      "      \"values\": [\n",
      "        0.0011809149535246906,\n",
      "        0.7867455841528153,\n",
      "        0.21207350089366006\n",
      "      ]\n",
      "    }\n",
      "  }\n",
      "}\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "+ jq\n",
      "+ curl -s -H 'Content-Type: application/json' -d '{\n",
      "    \"jsonData\": {\n",
      "        \"some_data\": {\n",
      "            \"names\": [\n",
      "                \"sepal_length\",\n",
      "                \"sepal_width\",\n",
      "                \"petal_length\",\n",
      "                \"petal_width\"\n",
      "            ],\n",
      "            \"some_ndarray\": [\n",
      "                [\n",
      "                    7.233,\n",
      "                    4.652,\n",
      "                    7.39,\n",
      "                    0.324\n",
      "                ]\n",
      "            ]\n",
      "        }\n",
      "    }\n",
      "}' http://192.168.39.230:30241/seldon/default/seldon-deployment-example/api/v0.1/predictions\n",
      "+ set +x\n"
     ]
    }
   ],
   "source": [
    "%%bash\n",
    "\n",
    "PAYLOAD=$(\n",
    "cat <<EOF\n",
    "{\n",
    "    \"jsonData\": {\n",
    "        \"some_data\": {\n",
    "            \"names\": [\n",
    "                \"sepal_length\",\n",
    "                \"sepal_width\",\n",
    "                \"petal_length\",\n",
    "                \"petal_width\"\n",
    "            ],\n",
    "            \"some_ndarray\": [\n",
    "                [\n",
    "                    7.233,\n",
    "                    4.652,\n",
    "                    7.39,\n",
    "                    0.324\n",
    "                ]\n",
    "            ]\n",
    "        }\n",
    "    }\n",
    "}\n",
    "EOF\n",
    ")\n",
    "\n",
    "NAMESPACE_NAME=default\n",
    "DEPLOYMENT_NAME=seldon-deployment-example\n",
    "\n",
    "HOST=$(minikube ip)\n",
    "PORT=$(kubectl get svc ambassador -o jsonpath='{.spec.ports[0].nodePort}')\n",
    "\n",
    "set -x\n",
    "curl -s -H \"Content-Type: application/json\" \\\n",
    "    -d \"${PAYLOAD}\" \\\n",
    "    \"http://${HOST}:${PORT}/seldon/${NAMESPACE_NAME}/${DEPLOYMENT_NAME}/api/v0.1/predictions\" | jq\n",
    "set +x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!minikube delete"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:gss-test]",
   "language": "python",
   "name": "conda-env-gss-test-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
